﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Linq;

namespace PushNotificationsHelper.WindowsApp
{
    public class TileNotification
    {
         public XDocument XmlTemplate { get; private set; }
        public TileTemplate ChosenTemplate { get; private set; }

        public string SecretKey { get; private set; }

        public string Sid { get; private set; }

        private TileNotification _instance;

        private TileNotification(string key, string sid) 
        {
            SecretKey = key;
            Sid = sid;
        }

        public static TileNotification CreateTileNotification(string key, string sid)
        {
            return new TileNotification(key, sid);
        }

        public TileNotification UsingTemplate(TileTemplate template)
        {
            ChosenTemplate = template;
            XmlTemplate = TileXmlTemplateFactory.GetXDocumentForTileTemplate(template);
            return this;
        }

        public TileNotification WithText(List<string> positionalText)
        {
            var textNodes = XmlTemplate.Descendants(XName.Get("text"));

            foreach (var item in positionalText)
            {
                var node = (from t in textNodes
                            let att = t.Attributes(XName.Get("id")).FirstOrDefault()
                            where att != null && att.Value == (positionalText.IndexOf(item)+1).ToString()
                            select t).FirstOrDefault();
                node.SetValue(item);                            
            }
            return this;
        }

        public TileNotification WithImages(Dictionary<int, string> imagesDictionary)
        {
            
            foreach (var item in imagesDictionary)
            {
                var textNodes = XmlTemplate.Descendants(XName.Get("Image"));
            }
            return this;
        }

        public bool SendPushNotification(string uri)
        {
            string request = XmlTemplate.ToString();
            var accessToken = GetAccessToken();

            string notificationType = "wns/tile";
            HttpWebRequest httpRequest = HttpWebRequest.Create(uri) as HttpWebRequest;
            httpRequest.Method = "POST";
            httpRequest.ContentType = "text/xml";
            httpRequest.Headers.Add("X-WNS-Type", notificationType);
            httpRequest.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));
            byte[] contentBytes = Encoding.UTF8.GetBytes(XmlTemplate.ToString());

            using (Stream requestStream = httpRequest.GetRequestStream())
                requestStream.Write(contentBytes, 0, contentBytes.Length);
            string test = string.Empty;
            using (HttpWebResponse webResponse = (HttpWebResponse)httpRequest.GetResponse())
                test = webResponse.StatusCode.ToString();

            return test.Equals("OK");
        }


        private WNSAuthToken GetAccessToken()
        {
            var urlEncodedSecret = HttpUtility.UrlEncode(SecretKey);
            var urlEncodedSid = HttpUtility.UrlEncode(Sid);

            var body =
              String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);

            string response;
            using (var client = new WebClient())
            {
                client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                response = client.UploadString("https://login.live.com/accesstoken.srf", body);
            }

            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(response)))
            {
                var ser = new DataContractJsonSerializer(typeof(WNSAuthToken));
                var oAuthToken = (WNSAuthToken)ser.ReadObject(ms);
                return oAuthToken;
            }
        }

        public void SendPushNotificationWithDelay(string uri)
        {
            for (int i = 0; i < 10; i++)
            {
                Task.Run(() => SendPushNotification(uri));
                Thread.Sleep(TimeSpan.FromSeconds(30));
            }
        }
    }
}
